/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
 * Description:
 * Author: g00421808
 * Create: 6/24/2022
 * Notes:
 */

#ifndef JSBIND_INVOKER_H
#define JSBIND_INVOKER_H

#include <memory>

#include "jsbind/value/value_trait.h"

namespace Jsb {


template<typename F>
struct InvokerInfo {
    InvokerInfo(F f) : invoker(f) {}

    const F invoker;
};

template<typename>
struct Invoker {
};

template<typename R, typename... P>
struct Invoker<R (*)(P...)> {
	template <typename F, typename... Args>
	static R InvokeFunction(F func, Args&&... args) {
		return (*func)(std::forward<P>(args)...);
	}

	template <class C, typename M, typename... Args>
	static R InvokeMethod(C &receiver, M method, Args&&... args) noexcept(false) {
		return (receiver.*method)(std::forward<P>(args)...);
	}
};

template<typename... P>
struct Invoker<void (*)(P...)> {
	template <typename F, typename... Args>
	static void InvokeFunction(F func, Args&&... args) {
		(*func)(std::forward<P>(args)...);
        return;
	}

	template <class C, typename M, typename... Args>
	static void InvokeMethod(C &receiver, M method, Args&&... args) noexcept(false) {
		(receiver.*method)(std::forward<P>(args)...);
        return;
	}
};

} // namespace Jsb
#endif //JSBIND_INVOKER_H
